﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Obra.Sync;
using NMock2;
using System.IO;
using Obra.Common;

namespace Obra.Test
{
    [TestFixture]
    public class SyncProvider_FileSystemSyncProviderTester : NMockTester
    {
        private IFileSystemService fileSystemService;

        private string tempDirectory;

        [SetUp]
        public override void SetUp()
        {
            base.SetUp();
            this.fileSystemService = this.Mockery.NewMock<IFileSystemService>();
            this.tempDirectory = TestHelper.CreateTempDirectory();
        }

        [TearDown]
        public override void TearDown()
        {
            base.TearDown();
            Directory.Delete(this.tempDirectory, true/*recursive*/);
        }

        [Test]
        public void Test()
        {
            string albumName = Path.GetRandomFileName();
            
            string albumDirectory = Path.Combine(
                this.tempDirectory,
                albumName);

            Directory.CreateDirectory(albumDirectory);

            string imagePath = TestHelper.CreateRandomFileWithExtension(
                albumDirectory,
                ".jpg");

            string imageName = Path.GetFileName(imagePath);
            
            FileSystemSyncServiceProvider service = new FileSystemSyncServiceProvider(
                this.tempDirectory,
                new SyncOptions(),
                this.fileSystemService);

            MediaItemMetadata mediaItemMetadata = new MediaItemMetadata()
            {
                Name = String.Format("{0}/{1}", albumName, imageName),
                LastModifiedUtc = (ulong) DateTime.Now.Ticks,
            };

            Stream imageStream = new FileStream(imagePath, FileMode.Open);
            Func<Stream> lazyLoadFunc = () => imageStream;

            using (Mockery.Ordered)
            {
                Expect.Once.On(this.fileSystemService).Method("GetMediaFiles")
                    .With(this.tempDirectory)
                    .Will(Return.Value(new List<FileInfo> { new FileInfo(imagePath), }));

                Expect.Once.On(this.fileSystemService).Method("ComputeChecksum")
                    .With(imagePath, ChecksumAlgorithm.MD5)
                    .Will(Return.Value("--checksum--"));

                Expect.Once.On(this.fileSystemService).Method("Delete")
                    .With(imagePath);

                Expect.Once.On(this.fileSystemService).Method("LazyLoad")
                    .With(imagePath)
                    .Will(Return.Value(lazyLoadFunc));

                Expect.Once.On(this.fileSystemService).Method("Write")
                    .With(imagePath, imageStream);
            }

            ISyncItemTransfer syncItemTransfer = new SyncItemTransfer(
                imageStream,
                mediaItemMetadata);

            service.Connect();
            var mediaFiles = service.EnumerateMediaFiles();
            service.ComputeChecksum(mediaItemMetadata);
            service.DeleteMediaFile(mediaItemMetadata);
            service.LoadChange(mediaItemMetadata.Name);
            service.SaveChange(syncItemTransfer);
            service.Disconnect();

            imageStream.Close();
        }
    }
}
